﻿using System;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
using System.Security.AccessControl;
using System.Collections.Generic;

namespace GSPMigratorCore.Helper
{
    public class SPPermissionHelper
    { 
        public static string SetItemPermission(string SPURL, SPRoleType oRoleType, SPFolder oFolder, string entity)
        {
            string ReturnVal = string.Empty;
            try
            {
                SPPrincipal oPrincipal = getSPPrincipal(SPURL, entity);
                if (oPrincipal != null)
                {
                    SetRoleAssignment(SPURL, oRoleType, oPrincipal, oFolder);
                }
                else 
                {
                    throw new Exception(string.Format("User/Group: {0} not found.", entity));
                }
            }
            catch (Exception ex)
            {
                ReturnVal += "Permission not set, reason: " + ex.Message;
            }
            return ReturnVal;
        }

        #region set role assignment

        internal static void SetRoleAssignment(string SPURL, SPRoleType spRoleType, SPPrincipal oPrincipal, SPFolder oFolder)
        {
            using (SPSite oSite = new SPSite(SPURL))
            {
                using (SPWeb oWeb = oSite.OpenWeb())
                {
                    SPRoleDefinition roleDefinition = oWeb.RoleDefinitions.GetByType(spRoleType);
                    
                    if (oPrincipal != null)
                    {
                        SPRoleAssignment roleAssignment = new SPRoleAssignment(oPrincipal);

                        roleAssignment.RoleDefinitionBindings.Add(roleDefinition);
                                                
                        oWeb.AllowUnsafeUpdates = true;

                        oFolder.Item.BreakRoleInheritance(false);//do not inherit default permissions
                        oFolder.Item.RoleAssignments.Add(roleAssignment);
                        oFolder.Item.Update();
                        
                        oWeb.AllowUnsafeUpdates = false;
                    }                    
                }
            }
        }

        internal static SPPrincipal getSPPrincipal(string SPURL, string entity)
        {
            SPPrincipal spPrincipal = null;
            using (SPSite oSite = new SPSite(SPURL))
            {
                using (SPWeb oWeb = oSite.OpenWeb())
                {
                    if (SPUtility.IsLoginValid(oWeb.Site, entity))
                    {
                        spPrincipal = oWeb.EnsureUser(entity) as SPPrincipal;
                    }
                    else
                    {
                        SPGroup groupToAdd = oWeb.SiteGroups[entity];
                        if (groupToAdd != null)
                        {
                            spPrincipal = groupToAdd as SPPrincipal;
                        }
                        else
                        {
                            //TODO: return error
                            throw new NotImplementedException();
                        }
                    }
                    return spPrincipal;
                }
            }
        }

        #endregion

    }

    public class FSPermissionHelper
    {
        public static List<string> ExtractFSPermissions(string dirPath, string domain, string spAdmin, bool useSPAdmin)
        {
            List<string> permissions = new List<string>();
            bool spAdminAdded = false;
            DirectorySecurity ds = new DirectorySecurity(dirPath, AccessControlSections.All);
            AuthorizationRuleCollection arc = ds.GetAccessRules(true, true, typeof(System.Security.Principal.NTAccount));
            foreach (FileSystemAccessRule ar in arc)
            {
                try
                {
                    string temp = string.Empty;
                    temp = ar.IdentityReference.Translate(typeof(System.Security.Principal.NTAccount)) + ": " + ar.AccessControlType + " " + ar.FileSystemRights;

                    if (temp.StartsWith(domain, StringComparison.OrdinalIgnoreCase))
                    {
                        permissions.Add(temp);
                        //writer.WriteLine(temp);
                    }
                    else if (!spAdminAdded) //no need keep repeating the system account permissions
                    {
                        permissions.Add(domain + @"\" + spAdmin + ": " + ar.AccessControlType + " " + ar.FileSystemRights);
                        //writer.WriteLine(domain + @"\" + spAdmin + ": " + ar.AccessControlType + " " + ar.FileSystemRights);
                        spAdminAdded = true;
                    }
                }
                catch (System.Security.Principal.IdentityNotMappedException e)
                {
                    if (!spAdminAdded)
                    {
                        if (useSPAdmin)
                        {
                            permissions.Add(domain + @"\" + spAdmin + ": " + ar.AccessControlType + " " + ar.FileSystemRights);
                            //writer.WriteLine(domain + @"\" + spAdmin + ": " + ar.AccessControlType + " " + ar.FileSystemRights);
                            spAdminAdded = true;
                        }
                    }
                }
            }
            return permissions;
        }
    }
}